package com.probiz.estore.catalog.service.impl;

import com.probiz.estore.core.service.impl.GenericManagerImpl;
import com.probiz.estore.catalog.dao.BaseCategoryDao;
import com.probiz.estore.catalog.model.BaseCategory;
import com.probiz.estore.catalog.model.BaseCategorySearchCriteria;
import com.probiz.estore.catalog.service.BaseCategoryManager;

import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.lang.reflect.InvocationTargetException;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.beanutils.BeanUtils;

/**
 * Created by Probiz
 * User: hoverming
 * Date: 2009-12-2
 * Time: 11:21:03
 */
public class BaseCategoryManagerImpl<T> extends GenericManagerImpl<T> implements BaseCategoryManager<T> {
	protected BaseCategoryDao<T> categoryDao;

	/*
	 * (non-Javadoc)
	 *
	 * @see com.probiz.estore.core.service.impl.GenericManagerImpl#init()
	 */
	@Override
	protected void initManager() {
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see com.probiz.estore.core.service.impl.GenericManagerImpl#onDelete(java.lang.Object)
	 */
	@Override
	protected void preDelete(T entity) {
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see com.probiz.estore.core.service.impl.GenericManagerImpl#onSave(java.lang.Object)
	 */
	@Override
	protected void preSave(T entity) {
	}


	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.catalog.service.CategoryManager#getCategoryById(java.lang.Integer)
	 */
	public BaseCategory getCategoryById(Integer categoryId) {
		return categoryDao.getCategoryById(categoryId);
	}

	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.catalog.service.CategoryManager#getCategoryTree(com.probiz.estore.catalog.model.Category, int, com.probiz.estore.catalog.model.CategorySearchCriteria)
	 */
	public BaseCategory getCategoryTree(BaseCategory parentCategory, int depth, BaseCategorySearchCriteria categorySearchCriteria) {
		return categoryDao.getCategoryTree(parentCategory, depth,categorySearchCriteria);
	}

	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.catalog.service.CategoryManager#getCategoryTree(com.probiz.estore.catalog.model.Category, int)
	 */
	public BaseCategory getCategoryTree(BaseCategory parentCategory, int depth) {
		return categoryDao.getCategoryTree(parentCategory, depth,new BaseCategorySearchCriteria());
	}

	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.catalog.service.CategoryManager#getCategoryList(com.probiz.estore.catalog.model.Category, int, com.probiz.estore.catalog.model.CategorySearchCriteria)
	 */
	public List<BaseCategory> getCategoryList(BaseCategory parentCategory, int depth,BaseCategorySearchCriteria categorySearchCriteria) {
		BaseCategory category = this.getCategoryTree(parentCategory, depth,categorySearchCriteria);

		List<BaseCategory> categoryList = new ArrayList<BaseCategory>();
		if (category != null) {
			categoryList.add(category);
			categoryList = convertTreeToList(category, categoryList);
		}
		return categoryList;
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.catalog.service.CategoryManager#getCategoryList(com.probiz.estore.catalog.model.Category, int)
	 */
	public List<BaseCategory> getCategoryList(BaseCategory parentCategory, int depth) {
		BaseCategory category = this.getCategoryTree(parentCategory, depth);

		List<BaseCategory> categoryList = new ArrayList<BaseCategory>();
		if (category != null) {
			categoryList.add(category);
			categoryList = convertTreeToList(category, categoryList);
		}
		return categoryList;
	}

	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.catalog.service.CategoryManager#getCategoryListById(java.lang.Integer, int)
	 */
	public List<BaseCategory> getCategoryListById(Integer parentCategoryId, int depth){
		BaseCategory parentCategory = this.getCategoryById(parentCategoryId);
		return this.getCategoryList(parentCategory, depth);
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.catalog.service.CategoryManager#getCategoryListById(java.lang.Integer, int, com.probiz.estore.catalog.model.CategorySearchCriteria)
	 */
	public List<BaseCategory> getCategoryListById(Integer parentCategoryId, int depth,BaseCategorySearchCriteria categorySearchCriteria){
		BaseCategory parentCategory = this.getCategoryById(parentCategoryId);
		return this.getCategoryList(parentCategory, depth,categorySearchCriteria);
	}

    /*
	 * (non-Javadoc)
	 * @see com.probiz.estore.catalog.service.CategoryManager#getCategoryListJSON(com.probiz.estore.catalog.model.Category, int, com.probiz.estore.catalog.model.CategorySearchCriteria)
	 */
	public JSONArray getCategoryListJSON(BaseCategory parentCategory, int depth,BaseCategorySearchCriteria categorySearchCriteria){
		List<BaseCategory>  categoryList = getCategoryList(parentCategory, depth,categorySearchCriteria);
		return convertListToJSONArray(categoryList);
	}

    /*
	 * (non-Javadoc)
	 * @see com.probiz.estore.catalog.service.CategoryManager#getCategoryListJSON(com.probiz.estore.catalog.model.Category, int)
	 */
	public JSONArray getCategoryListJSON(BaseCategory parentCategory, int depth){
		List<BaseCategory>  categoryList = getCategoryList(parentCategory, depth);
		return convertListToJSONArray(categoryList);
	}

    /*
	 * (non-Javadoc)
	 * @see com.probiz.estore.catalog.service.CategoryManager#updateCategoriesSortOrder(java.lang.Integer[])
	 */
	public void updateCategoriesSortOrder(Integer[] categoryIds)  {
		for (int i = 0; i < categoryIds.length; i++) {
			Integer categoryId = categoryIds[i];
			T category=getById(categoryId);
			if(category==null)continue;
			try {
				BeanUtils.setProperty(category,"sortOrder",(i+1));
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}
			save(category);
		}
	}

    /*
	 * (non-Javadoc)
	 * @see com.probiz.estore.catalog.service.CategoryManager#countSubCategoryById(java.lang.Integer)
	 */
	public Integer countSubCategoryById(Integer categoryId){
		return categoryDao.countSubCategoryById(categoryId);
	}

    /**
     * 将目录List对象转换为JSONArray对象
     * @param categoryList  目录列表
     * @return 目录JSONArray对象
     */
    private JSONArray convertListToJSONArray(List<BaseCategory> categoryList) {
        JSONArray categoryArray = new JSONArray();
        for(BaseCategory category: categoryList){
            JSONObject categoryJSON = new JSONObject();
            categoryJSON.put("categoryId", category.getCategoryId());
            categoryJSON.put("categoryCode", category.getCategoryCode());
            categoryJSON.put("categoryName", category.getCategoryName());
            categoryJSON.put("depth", category.getDepth());
            categoryJSON.put("hasChildren", category.getHasChildren());
            categoryJSON.put("parentId", category.getParentId());
            categoryJSON.put("categoryPath", category.getCategoryPath());
            categoryArray.add(categoryJSON);
        }
        return categoryArray;
    }

    /**
     * 将目录树转变成目录列表（递归方法）
     * @param parentCategory 起始节点
     * @param categoryList 目录列表
     * @return 目录列表
     */
    private List<BaseCategory> convertTreeToList(BaseCategory parentCategory,
                                                 List<BaseCategory> categoryList) {
        Iterator iterator = parentCategory.getChildren().iterator();
        while (iterator.hasNext()) {
            BaseCategory category = (BaseCategory) iterator.next();
            // 修改上一个的nextDifference;
            if (categoryList.size() > 0) {
                BaseCategory preCategory = categoryList
                        .get(categoryList.size() - 1);
                if (category.getDepth() < preCategory.getDepth()) {
                    preCategory.setNextDifference(preCategory.getDepth()
                            - category.getDepth());
                }else{
                    preCategory.setNextDifference(0);
                }
            }
            categoryList.add(category);
            convertTreeToList(category, categoryList);
            iterator.remove();
        }
        return categoryList;
    }
    
    public Integer getCategoryIdByCategoryPath(String categoryPath){
    	String[] categoryIds = categoryPath.split("\\.");
    	return Integer.valueOf(categoryIds[categoryIds.length-1]);
    }
    
    /*
     * (non-Javadoc)
     * @see com.probiz.estore.catalog.service.BaseCategoryManager#countCategoryTotal()
     */
	public Long countCategoryTotal(){
		return categoryDao.countCategoryTotal();
	}
}
